package com.schd.base.exception;

import com.schd.base.enumerate.ModuleType;
import org.apache.log4j.Logger;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;

/**
 * @author 陈刚
 * @version 1.0
 * @project guaranty
 * @package com.haorui.commons.core.exception
 * @createDate 2015/4/7 0007 11:21
 * @modfiyDate
 * @function 基础异常类
 */
public abstract class BaseException extends Exception  {

    private static final long serialVersionUID = 3987086765649254682L;
    private static final Logger logger = Logger.getLogger(BaseException.class);
    protected ModuleType module;


    /**
     * 设置模块属性
     */
    protected abstract void setModuleType();


    public BaseException(String message) {
        super(message);
        this.setModuleType();
        this.saveException(message);
    }

    public BaseException(String message, Exception e) {
        super(message, e);
        this.setModuleType();
        StringBuilder sb = new StringBuilder();

        if (e != null) {
            sb.append("Exception : ").append(e.toString());
            if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
                for(StackTraceElement ste : e.getStackTrace()){
                    sb.append(System.getProperty("line.separator"));
                    sb.append("Class : ").append(ste.getClassName());
                    sb.append(" | Method : ").append(ste.getMethodName());
                    sb.append(" | line : ").append(ste.getLineNumber());
                }
            }
            this.saveException(e.toString(), sb.toString());
        }
    }

    /**
     * 将CheckedException转换为UncheckedException.
     */
    public static RuntimeException unchecked(Exception e) {
        if (e instanceof RuntimeException) {
            return (RuntimeException) e;
        } else {
            return new RuntimeException(e);
        }
    }

    /**
     * 将ErrorStack转化为String.
     */
    public static String getStackTraceAsString(Exception e) {
        StringWriter stringWriter = new StringWriter();
        e.printStackTrace(new PrintWriter(stringWriter));
        return stringWriter.toString();
    }

    /**
     * 判断异常是否由某些底层的异常引起.
     */
    public static boolean isCausedBy(Exception ex,
                                     Class<? extends Exception>... causeExceptionClasses) {
        Throwable cause = ex.getCause();
        while (cause != null) {
            for (Class<? extends Exception> causeClass : causeExceptionClasses) {
                if (causeClass.isInstance(cause)) {
                    return true;
                }
            }
            cause = cause.getCause();
        }
        return false;
    }

    /**
     * 保存异常信息到数据库
     * @param message 消息
     * @param cause  原因
     */
    protected void saveException(String message, String... cause){

        String causeString="";
        if(cause.length>0){
            causeString=Arrays.toString(cause);
        }
        logger.error("[<<" + module.getModuleName() + ">>]异常:" + message+"\n"+ causeString);
    }


}
